﻿using System.Collections.Generic;
using System.Linq;
using Common.DTO;
using System;

namespace Database.Repositories
{
    public class UserAccountRepository : RepositoryBase<UserAccount>, IRepository<UserAccountDTO>
    {
        //private readonly UserAccountMapper _userAccountMapper;

        public UserAccountRepository()
        {
            //_userAccountMapper = new UserAccountMapper();
        }

        public Guid Create(UserAccountDTO userAccount)
        {
            var userAccountEntity = Mapper.Map(userAccount);
            var id = Guid.NewGuid();
            userAccountEntity.Id = id;

            DbContext.UserAccountSet.Add(userAccountEntity);
            DbContext.SaveChanges();

            return id;
        }

        public UserAccountDTO Read(Guid id)
        {
            try
            {
                var entity = DbContext.UserAccountSet.FirstOrDefault(x => x.Id == id);
                return Mapper.Map(entity);
                
            }
            catch (Exception)
            {
                return null;
            }
        }

        public bool Update(UserAccountDTO userAccount)
        {
            var userAccountEntity = DbContext.UserAccountSet.FirstOrDefault(
                x => x.Id == userAccount.Id);
            if (userAccountEntity == null)
                return false;

            userAccountEntity.Name = userAccount.Name;
            userAccountEntity.Email = userAccount.Email;

            return SaveChanges();
        }

        public bool Delete(Guid id)
        {
            if (!MarkUserAccountForDeletion(id))
                return false;

            SaveChanges(3);
            return true;
        }

        public bool DeleteAll()
        {
            var allGuids = DbContext.UserAccountSet.Select(x => x.Id).ToList();
            allGuids.ForEach(delegate(Guid id)
            {
                MarkUserAccountForDeletion(id);
            });
            return SaveChanges(allGuids.Count * 3);
        }

        private bool MarkUserAccountForDeletion(Guid id)
        {
            var userAccountEntity = DbContext.UserAccountSet.FirstOrDefault(
                x => x.Id == id);
            if (userAccountEntity == null)
                return false;

            if (userAccountEntity.Character != null)
                DbContext.CharacterSet.Remove(userAccountEntity.Character);
            
            DbContext.UserAccountSet.Remove(userAccountEntity);

            return true;
        }

        private bool SaveChanges(int expectedRowsAffected = 1)
        {
            var rowsAffected = DbContext.SaveChanges();
            if (rowsAffected == expectedRowsAffected)
                return true;
            else
                return false;
        }
    }
}